#include "riscv.h"
#include "proc.h"
#include"param.h"
#include"defs.h"
//#include <stddef.h> // For NULL definition

extern void user_main();        // 用户态程序入口
extern void uservec();          // S-mode trap 处理入口（trap.S）
extern void userret();          // 从 S-mode 跳回 U-mode 的函数（userret.S）
extern char stack0[];

void main() {
    //superviseMode的特权进行转移，打开用户态的中断
    uint64 x=r_sstatus();
    x&=~SSTATUS_SPP;
    x|=SSTATUS_SPIE;

    //初始化分配用户栈，并初始化栈指针
    char* userStack=kalloc();
    //if (userStack == NULL) {
        //输出异常
    //}

    //初始化陷阱帧
    struct trapframe* tf=(struct trapframe*)(stack0+PGSIZE-sizeof(struct trapframe));//陷阱帧
    //memset(tf,0,sizeof(tf));
    tf->sp = ((uint64)(userStack + PGSIZE)) & ~0xF;// 确保 16 字节对齐
    //注意，空间是从下到上去进行开辟的，但是栈是从上到下去生长的，因此这里我们要初始化在最顶测
    tf->sepc = ((uint64)user_main);//sret的返回地址

    // 设置 S-mode trap 入口，中断后进入trap.S
    w_stvec((uint64)uservec);
    w_sscratch((uint64)tf);
    //开始跳转进入用户态
    asm volatile(
        "mv a0, %0\n"// 把 &tf 放入 a0，传给 userret，初始化用户态的状态
        "call userret\n"
        :
        : "r"(tf)
        : "memory"
    );
    //空循环等待
    while (1) {
        //输出异常
    }
}
